package com.ambitor.ipro.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class TemplateMatcher {
	
	private final static String IPRO_TITLE_REGEX = "ipro_(top|bot){1}_[0-9]{1}";
	
	private final static String IPRO_TITLE_TOP_REGEX = "<[\\s]*(div|table){1}[^<>/]+ipro_top(_[0-9]{1})?";
	
	private final static String IPRO_TITLE_BOT_REGEX = "<[\\s]*(div|table){1}[^<>/]+ipro_bot(_[0-9]{1})?";

	public static String insert(String text, String inserts) {
		if (text == null || inserts == null)
			return null;

		Pattern p = Pattern.compile(IPRO_TITLE_REGEX, Pattern.CASE_INSENSITIVE);
		Matcher m = p.matcher(inserts);
		if(!m.find()) return null;
		String [] strs = m.group().split("_");
		String type = strs[1]; 
		int pos = Integer.parseInt(strs[2]);
		
		String regex = type.equals("top")?IPRO_TITLE_TOP_REGEX:IPRO_TITLE_BOT_REGEX;
		StringBuilder sb = new StringBuilder(text);
		p = Pattern.compile(regex, Pattern.CASE_INSENSITIVE);
		m = p.matcher(sb);
		int index=1, position=-1, end=-1;
		while(m.find()) {
			if(m.group(m.groupCount())==null) index = 1;
			else {
				String s = m.group(m.groupCount());
				index = Integer.parseInt(s.substring(1));
			}
			if(index==pos) {
				end = findEndPosition(sb, inserts, type, m.start());
				sb.delete(m.start(), end);
				sb.insert(m.start(), inserts);
				return sb.toString();
			} else if(index>pos){
				sb.insert(m.start(), inserts);
				return sb.toString();
			}
			position = m.start();
		}
		if(position!=-1) {
			end = findEndPosition(sb, inserts, type, position);
			sb.insert(end, inserts);
		} else {
			if(type.equalsIgnoreCase("top")) sb.insert(0, inserts);
			else sb.append(inserts);
		}
		return sb.toString();
	}
	
	private static int findEndPosition(StringBuilder text, String inserts, String type, int start) {
		if (text == null) return -1;

		int stackIndex = 0;
		Pattern p = Pattern.compile("(<[\\s]*(div|table){1})|(<[\\s]*/[\\s]*(div|table){1}[\\s]*>)", Pattern.CASE_INSENSITIVE);
		Matcher m = p.matcher(text.substring(start));
		Pattern headTagPattern = Pattern.compile("<[\\s]*(div|table){1}", Pattern.CASE_INSENSITIVE);
		while(m.find()) {
			String matchedString = m.group();
			Matcher m1 = headTagPattern.matcher(matchedString);
			if(m1.matches()) stackIndex++;
			else stackIndex--;

			if (stackIndex == 0) {
				return start + m.end();
			}
		}
		
		return 0;
	}
	
	public static String delete(String text, String title) {
		if (text == null || title == null)
			return text;

		int stackIndex=0, start=0, end=0, del_len = 0;
		StringBuilder sb = new StringBuilder(text);
		Pattern p = Pattern.compile("<[\\s]*(div|table){1}[^<>/]+title=\""+title, Pattern.CASE_INSENSITIVE);
		Matcher m = p.matcher(text);
		while(m.find()) {
			start = m.start();
			Pattern p1 = Pattern.compile("<[\\s]*(div|table){1}|<[\\s]*/[\\s]*(div|table){1}[\\s]*>", Pattern.CASE_INSENSITIVE);
			Matcher m1 = p1.matcher(text.substring(m.start()));
			Pattern headTagPattern = Pattern.compile("<[\\s]*/[\\s]*(div|table){1}[\\s]*>", Pattern.CASE_INSENSITIVE);
			while(m1.find()) {
				String matchedString = m1.group();
				Matcher m2 = headTagPattern.matcher(matchedString);
				if (m2.matches())
					stackIndex--;
				else
					stackIndex++;

				if (stackIndex == 0) {
					end = m1.end();
					sb.delete(start-del_len, start+end-del_len);
					del_len += end;
					break;
				}
			}
		}
		return sb.toString();
	}
	
	public static void main(String[] args) {
		try {
			File f = new File("xx.html");
			File of = new File("out.html");
			if(!of.exists()) of.createNewFile();
			
			InputStream is = new FileInputStream(f);
			OutputStream out = new FileOutputStream(of);
			byte[] bytes = new byte[is.available()];
			is.read(bytes);
			String text = new String(new String(bytes));
			
			text = delete(text, "ipro");
			out.write(text.getBytes());
			out.close();
		} catch(Exception e) {
			e.printStackTrace();
		}
	}
	
}
